﻿<?xml version="1.0" encoding="utf-8" ?>
<examples>  
  <!-- 
    Beware that recursive includes will result in duplicate comments if the path used also matches the value after it's been replaced.
    For example, using /examples/example instead of //example for includes within this file solves the problem of the path matching both the 
    target example and the 'included' example in subsequent replacements.
  -->
  
  <!-- ******************** Image examples ******************** -->

  <example id="ImageResources">
    <para>The following images are embedded in the AIP assembly for use with <see cref="ResourceAutoInputProtectionImageProvider"/>.</para>
    <para>
      <include file="images.xml" path='//group[@id="ImageResources"]/*'/>
    </para>
  </example>

  <example id="TextProvider" type="images">
    <para>The following images were generated using various <see cref="AutoInputProtectionTextProvider"/> implementations.</para>
    <para>
      <include file='images.xml' path='//group[@id="BasicEnglish"]/*'/>
      <include file='images.xml' path='//group[@id="RandomCharacters"]/*'/>
    </para>
  </example>
  <example id="ImageProvider" type="images">
    <para>The following images were generated using various <see cref="AutoInputProtectionImage"/> implementations.</para>
    <para>
      <include file='images.xml' path='//group[@id="LineNoise"]/*'/>
      <include file='images.xml' path='//group[@id="Resource"]/*'/>
    </para>
  </example>
  <example id="FilterProvider" type="images">
    <para>The following images were generated using various pre and post-process <see cref="AutoInputProtectionFilterProvider"/> implementations.</para>
    <para>
      <include file='images.xml' path='//group[@id="Crosshatch"]/*'/>
      <include file='images.xml' path='//group[@id="TranslucentBarsOverlay"]/*'/>
    </para>
  </example>

  <example id="Background" type="images">
    <para>
      The following images were generated using various <see cref="BackgroundAutoInputProtectionImage"/> implementations.
    </para>
    <para>
      <include file='images.xml' path='//group[@id="Background"]/*'/>
      <include file='images.xml' path='//group[@id="Resource"]/*'/>
    </para>
  </example>
  <example id="Partitioned" type="images">
    <para>
      The following images were generated using various <see cref="PartitionedAutoInputProtectionImage"/> implementations.
    </para>
    <para>
      <include file='images.xml' path='//group[@id="Partitioned"]/*'/>
    </para>
  </example>
  
  <example id="BasicEnglish" type="images">
    <para>The following images were generated using <see cref="BasicEnglishAutoInputProtectionTextProvider"/>.</para>
    <para>
      <include file='images.xml' path='//group[@id="BasicEnglish"]/*'/>
    </para>
  </example>
  <example id="LineNoise" type="images">
    <para>The following images were generated using <see cref="LineNoiseAutoInputProtectionImage"/>.</para>
    <para>
      <include file='images.xml' path='//group[@id="LineNoise"]/*'/>
    </para>
  </example>
  <example id="Crosshatch" type="images">
    <para>The following images were generated using <see cref="CrosshatchAutoInputProtectionFilterProvider"/>.</para>
    <para>
      <include file='images.xml' path='//group[@id="Crosshatch"]/*'/>
    </para>
  </example>
  <example id="RandomCharacters" type="images">
    <para>The following images were generated using <see cref="RandomCharactersAutoInputProtectionTextProvider"/>.</para>
    <para>
      <include file='images.xml' path='//group[@id="RandomCharacters"]/*'/>
    </para>
  </example>
  <example id="Resource" type="images">
    <para>The following images were generated using <see cref="BackgroundAutoInputProtectionImage"/> and <see cref="ResourceAutoInputProtectionImageProvider"/>.</para>
    <para>
      <include file='images.xml' path='//group[@id="Resource"]/*'/>
    </para>
  </example>
  <example id="TranslucentBarsOverlay" type="images">
    <para>The following images were generated using <see cref="TranslucentBarsOverlayAutoInputProtectionFilterProvider"/>.</para>
    <para>
      <include file='images.xml' path='//group[@id="TranslucentBarsOverlay"]/*'/>
    </para>
  </example>

  <!-- ******************** Configuration examples ******************** -->

  <example id="configSections">
    <para>
      The following example uses the appropriate configuration in a web.config file so that the 
      <see cref="DaveSexton.Web.Controls.Configuration.AutoInputProtectionSection">autoInputProtection</see> section can be used.
    </para>
    <note>
      The <c>autoInputProtection</c> section is not required to use <see cref="AutoInputProtectionControl">AutoInputProtectionControl</see> 
      with the default settings and providers.  You only need to add it if you want to customize settings and providers.
    </note>
    <code><![CDATA[<?xml version="1.0" ?>
<configuration>
  <configSections>
    <section name="autoInputProtection"
             type="DaveSexton.Web.Controls.Configuration.AutoInputProtectionSection, DaveSexton.AutoInputProtection"/>
  </configSections>
  
  <autoInputProtection>
  </autoInputProtection>
</configuration>]]></code>
  </example>

  <example id="configSession">
    <para>
      The following example uses <ses cref="AutoInputProtection.UserMode">UserMode</ses> set to <see cref="AutoInputProtectionUserMode.None">None</see> 
      and <see cref="AutoInputProtection.PersistenceMode">PersistenceMode</see> set to <see cref="AutoInputProtectionPersistenceMode.Session">Session</see>
      so that challenges will be stored in session state.  In-process session state is enabled and <see cref="AutoInputProtectionSessionRequestHandler"/>
      is used so that AIP can retrieve images from a user's session.
    </para>
    <note>
      Setting <see cref="AutoInputProtection.PersistenceMode">PersistenceMode</see> to <see cref="AutoInputProtectionPersistenceMode.Session">Session</see>
      will cause the <see cref="AutoInputProtectionControl.ValidationTimeout">ValidationTimeout</see>, <see cref="AutoInputProtectionControl.ValidationKeepAlive">ValidationKeepAlive</see>,
      <see cref="AutoInputProtectionControl.RequestTimeout">RequestTimeout</see> and <see cref="AutoInputProtectionControl.RequestKeepAlive">RequestKeepAlive</see> properties
      to be ignored for all instances of <see cref="AutoInputProtectionControl" />.
    </note>
    <code><![CDATA[<?xml version="1.0" ?>
<configuration>
  <configSections>
    <section name="autoInputProtection"
             type="DaveSexton.Web.Controls.Configuration.AutoInputProtectionSection, DaveSexton.AutoInputProtection"/>
  </configSections>
  
  <autoInputProtection userMode="None" persistenceMode="Session">
  </autoInputProtection>
  
  <system.web>
    <!-- Enable in-process session state -->
    <sessionState mode="InProc"/>
    
    <httpHandlers>
      <!-- use the session request handler instead of the typical request handler -->
      <add verb="GET" path="AIP.ashx"
           type="DaveSexton.Web.Controls.AutoInputProtectionSessionRequestHandler, DaveSexton.AutoInputProtection"/>
    </httpHandlers>
  </system.web>
</configuration>]]></code>
  </example>

  <example id="handler">
    <code><![CDATA[<?xml version="1.0"?>
<configuration>
  <system.web>
    <httpHandlers>
      <add verb="GET" path="AIP.ashx"
           type="DaveSexton.Web.Controls.AutoInputProtectionRequestHandler, DaveSexton.AutoInputProtection"/>
    </httpHandlers>
  </system.web>
</configuration>]]></code>
    <note>
      This is the minimum configuration that is required to use <see cref="AutoInputProtectionControl"/>.
    </note>
    <note>
      The file to which this handler refers does not actually exist.  ASP.NET routes requests to the appropriate handler automatically.
    </note>
  </example>
  
  <example id="TextProvider" type="config">
    <include file="examples.xml" path='/examples/example[@id="BasicEnglish"][@type="config"]/*'/>
  </example>
  <example id="ImageProvider" type="config">
    <include file="examples.xml" path='/examples/example[@id="LineNoise"][@type="config"]/*'/>
  </example>
  <example id="FilterProvider" type="config">
    <include file="examples.xml" path='/examples/example[@id="Crosshatch"][@type="config"]/*'/>
  </example>

  <example id="Background" type="config">
    <include file="examples.xml" path='/examples/example[@id="Resource"][@type="config"]/*'/>
  </example>
  <example id="Partitioned" type="config">
    <include file="examples.xml" path='/examples/example[@id="LineNoise"][@type="config"]/*'/>
  </example>
  
  <example id="BasicEnglish" type="config">
    <para>The following example adds a <see cref="BasicEnglishAutoInputProtectionTextProvider"/> to the web.config file and sets it as the default:</para>
    <code><![CDATA[<autoInputProtection defaultTextProvider="basic english">
  <textProviders>
    <add name="basic english"
         type="DaveSexton.Web.Controls.BasicEnglishAutoInputProtectionTextProvider, DaveSexton.AutoInputProtection"
         colors="Red,Green,Blue,Brown" fonts="Times New Roman,Arial,Lucida Sans"
         minimumFontSize="20" maximumFontSize="35"/>
  </textProviders>
</autoInputProtection>]]></code>
  </example>
  <example id="LineNoise" type="config">
    <para>The following example adds a <see cref="LineNoiseAutoInputProtectionImageProvider"/> to the web.config file and sets it as the default:</para>
    <code><![CDATA[<autoInputProtection defaultImageProvider="line noise">
  <imageProviders>
    <add name="line noise"
         type="DaveSexton.Web.Controls.LineNoiseAutoInputProtectionImageProvider, DaveSexton.AutoInputProtection"/>
  </imageProviders>
</autoInputProtection>]]></code>
  </example>
  <example id="Crosshatch" type="config">
    <para>The following example adds a <see cref="CrosshatchAutoInputProtectionFilterProvider"/> to the web.config file:</para>
    <code><![CDATA[<autoInputProtection>
  <filters>
    <add name="crosshatch"
         type="DaveSexton.Web.Controls.CrosshatchAutoInputProtectionFilterProvider, DaveSexton.AutoInputProtection"
         colors="Black,Blue,Green,Red,Fuchsia" opacity=".35"/>
  </filters>
</autoInputProtection>]]></code>
  </example>
  <example id="Resource" type="config">
    <para>The following example adds a <see cref="ResourceAutoInputProtectionImageProvider"/> to the web.config file and sets it as the default:</para>
    <code><![CDATA[<autoInputProtection defaultImageProvider="resource">
  <imageProviders>
    <add name="resource"
         type="DaveSexton.Web.Controls.ResourceAutoInputProtectionImageProvider, DaveSexton.AutoInputProtection"/>
  </imageProviders>
</autoInputProtection>]]></code>
  </example>
  <example id='RandomCharacters' type='config'>
    <para>The following example adds a <see cref="RandomCharactersAutoInputProtectionTextProvider"/> to the web.config file and sets it as the default:</para>
    <code><![CDATA[<autoInputProtection defaultTextProvider="random characters">
  <textProviders>
    <add name="random characters"
         type="DaveSexton.Web.Controls.RandomCharactersAutoInputProtectionTextProvider, DaveSexton.AutoInputProtection"
         colors="Red,Green,Blue,Brown" fonts="Times New Roman,Arial,Lucida Sans"
         minimumFontSize="20" maximumFontSize="35"/>
  </textProviders>
</autoInputProtection>]]></code>
  </example>
  <example id="TranslucentBarsOverlay" type="config">
    <para>The following example adds a <see cref="TranslucentBarsOverlayAutoInputProtectionFilterProvider"/> to the web.config file:</para>
    <code><![CDATA[<autoInputProtection>
  <filters>
    <add name="vertical bars"
         type="DaveSexton.Web.Controls.TranslucentBarsOverlayAutoInputProtectionFilterProvider, DaveSexton.AutoInputProtection"
         colors="Blue,Green" orientation="vertical" opacity=".25"/>
    <add name="horizontal bars"
         type="DaveSexton.Web.Controls.TranslucentBarsOverlayAutoInputProtectionFilterProvider, DaveSexton.AutoInputProtection"
         colors="Yellow,Red,Fuchsia" orientation="horizontal" opacity=".4" allowOverlap="false"/>
  </filters>
</autoInputProtection>]]></code>
  </example>

  <!-- ******************** Custom provider examples ******************** -->

  <example id="TextProvider" type="custom">
    <para>The following code example defines a custom text provider that generates a string with random numbers.</para>
    <code><![CDATA[using System;
using DaveSexton.Web.Controls;

namespace MyLib
{
  public sealed class RandomNumbersAutoInputProtectionTextProvider
    : AutoInputProtectionTextProvider
  {
    public override string GenerateRandomAutoInputProtectionText()
    {
      return RandomString.Create(MinimumCharacters, MaximumCharacters, 
        CharacterSets.PositiveDigits, null);
    }
  }
}]]></code>
  </example>
  
  <example id="ImageProvider" type="custom">
    <para>
      The following code example defines a custom image provider that creates a <see cref="PartitionedAutoInputProtectionImage"/>
      with a pure white surface on which the text is rendered.  This example illustrates the most basic implementation of a class
      that derives from <see cref="PartitionedAutoInputProtectionImageProvider"/> as it uses the 
      <see cref="PartitionedAutoInputProtectionImageProvider.GenerateImage(Size,AutoInputProtectionTextProvider)">GenerateImage</see> 
      method to create an instance of <see cref="PartitionedAutoInputProtectionImage"/>, which uses a white surface by default.
    </para>
    <code><![CDATA[using System;
using DaveSexton.Web.Controls;

namespace MyLib
{
  public sealed class WhiteBackgroundAutoInputProtectionImageProvider
    : PartitionedAutoInputProtectionImageProvider
  {
    public override AutoInputProtectionImage GenerateAutoInputProtectionImage(
      string name, System.Drawing.Size size, AutoInputProtectionTextProvider textProvider)
    {
      return GenerateImage(size, textProvider);
    }

    public override AutoInputProtectionImage GenerateRandomAutoInputProtectionImage(
      System.Drawing.Size size, AutoInputProtectionTextProvider textProvider)
    {
      return GenerateImage(size, textProvider);
    }
  }
}]]></code>
  </example>
  
  <example id="FilterProvider" type="custom">
    <para>
      The following code example defines a custom filter provider that renders a translucent blue rectangle over the entire
      image.  The value of the <em>Opacity</em> property can be assigned in the configuration file using an <em>opacity</em>
      attribute; e.g., <c>&lt;add name="blue overlay" type="..." opacity=".6" /&gt;</c>.
    </para>
    <code><![CDATA[using System;
using System.Drawing;
using System.Configuration.Provider;
using DaveSexton.Web.Controls;

namespace MyLib
{
  public sealed class BlueOverlayAutoInputProtectionFilterProvider
    : AutoInputProtectionFilterProvider
  {
    public float Opacity { get; set; }

    public override bool CanPreProcess
    {
      get { return false; }
    }

    public override bool CanPostProcess
    {
      get { return true; }
    }

    public override void Initialize(string name, NameValueCollection config)
    {
      if (config == null)
        throw new ArgumentNullException("config");

      if (string.IsNullOrEmpty(name))
        name = "SolidColorAutoInputProtectionFilterProvider";

      if (string.IsNullOrEmpty(config["description"]))
      {
        config.Remove("description");
        config.Add("description", "Solid Color Auto-Input Protection Filter Provider");
      }

      base.Initialize(name, config);

      ProviderHelper helper = new ProviderHelper(config);

      Opacity = helper.ParseSingle("opacity", false, .15F);

      // Throw an exception if unrecognized attributes remain
      if (config.Count > 0)
      {
        string attr = config.GetKey(0);

        if (!string.IsNullOrEmpty(attr))
          throw new ProviderException("Unrecognized attribute: " + attr);
      }
    }

    public override void PreProcess(Graphics graphics, Size imageSize)
    {
      throw new NotSupportedException();
    }

    public override void PostProcess(Graphics graphics, Size imageSize)
    {
      using (Brush brush = new SolidBrush(
        Color.FromArgb((int) (Opacity * 255), Color.Blue)))
      {
        graphics.FillRectangle(brush, 0, 0, imageSize.Width, imageSize.Height);
      }
    }
  }
}]]></code>
  </example>

  <!-- ******************** Misc code examples ******************** -->

  <example id="ProviderHelper">
    <para>
      The following example uses <see cref="ProviderHelper"/> in the <see cref="System.Configuration.Provider.ProviderBase.Initialize">Initialize</see>
      method override of a class that derives from <see cref="System.Configuration.Provider.ProviderBase"/> to parse the values of the
      <em>colors</em>, <em>minimumCharacters</em> and <em>maximumCharacters</em> attributes and assigns them to corresponding fields.
    </para>
    <code><![CDATA[public override void Initialize(string name, NameValueCollection config)
{
  if (config == null)
    throw new ArgumentNullException("config");

  base.Initialize(name, config);

  ProviderHelper helper = new ProviderHelper(config);

  minimumCharacters = helper.ParseInt32("minimumCharacters", false, 4);
  maximumCharacters = helper.ParseInt32("maximumCharacters", false, 6);

  if (maximumCharacters < 1 || maximumCharacters < minimumCharacters)
    throw ProviderHelper.CreateException(null,
      "The value of maximumCharacters must be a positive integer or zero and must be greater than or equal to minimumCharacters.");

  if (minimumCharacters < 1)
    throw ProviderHelper.CreateException(null, "The value of minimumCharacters must be a positive integer or zero.");

  colors.AddRange(helper.ParseCollection<Color>("colors", false, true, true, ',') ?? new List<Color>(0));

  if (colors.Count == 0)
    throw ProviderHelper.CreateException(null, "The colors attribute is required and must specify at least one color.");
}]]></code>
  </example>
</examples>